<?php

namespace App\Services\WxMaterial;

use App\Models\WxMaterial;
use App\Models\WxMaterialNew;
use App\Models\WxMaterialNewImg;
use App\Services\EasyWechat;
use App\Services\SysFileService;
use App\Services\WxErrorService;
use EasyWeChat\Kernel\Messages\Article;
use EasyWeChat\Kernel\Messages\News;
use EasyWeChat\Kernel\Messages\NewsItem;

/**
 * 图文素材业务逻辑
 * @package App\Services\WxMaterial
 */
class WxMaterialNews implements WxMaterialInterface
{
    /**
     * 保存素材数据
     * @param $data
     */
    public function save($data)
    {
        \DB::beginTransaction();
        try {
            $materialData = $data['material_data'];
            $newsList = $data['news_list'];
            if (!empty($materialData['material_id'])) {
                $findMaterial = WxMaterial::find($materialData['material_id']);
            } else {
                $findMaterial = new WxMaterial;
            }
            $findMaterial->cat_id = $materialData['cat_id'];
            $findMaterial->type = 'news';
            $findMaterial->is_forever = $materialData['is_forever'];
            $previewData = [];
            if ($newsList) {
                foreach ($newsList as $v) {
                    $previewData[] = [
                        'title' => $v['title'],
                        'thumb_view_url' => $v['thumb_view_url'],
                        'digest' => empty($v['digest']) ? mb_substr(strip_tags($v['content']), 0, 64, 'utf-8') : $v['digest'],
                    ];
                }
            }
            $findMaterial->preview_data = $previewData;
            $findMaterial->save();
            $materialId = $findMaterial['material_id'] ?? 0;
            if (empty($materialId)) {
                throw new \Exception('生成素材ID失败');
            }
            //保存文章列表
            if (!empty($newsList)) {
                WxMaterialNew::where('material_id', $materialId)->delete();
                foreach ($newsList as $v) {
                    if (!empty($v['new_id'])) {
                        $findNew = WxMaterialNew::find($v['new_id']);
                    } else {
                        $findNew = new WxMaterialNew;
                    }
                    $findNew->material_id = $materialId;
                    $findNew->title = $v['title'] ?? '';
                    $findNew->thumb_view_url = $v['thumb_view_url'] ?? '';
                    $findNew->author = $v['author'] ?? '';
                    $findNew->digest = empty($v['digest']) ? mb_substr(strip_tags($v['content']), 0, 64, 'utf-8') : $v['digest'];
                    $findNew->show_cover_pic = $v['show_cover_pic'] ?? 0;
                    $findNew->content = $v['content'];
                    $findNew->content_source_url = $v['content_source_url'];
                    $findNew->news_click_url = $v['news_click_url'] ?? '';
                    $findNew->need_open_comment = $v['need_open_comment'] ?? 0;
                    $findNew->only_fans_can_comment = $v['only_fans_can_comment'];
                    $findNew->save();
                    $findNew->restore();
                }
            }

            //永久素材则异步获取mediaId
            if ($findMaterial->is_forever) {

            }
            \DB::commit();
        } catch (\Exception $e) {
            \DB::rollBack();
            throw new \Exception($e->getMessage());
        }
    }

    /**
     * 删除素材
     * @param $materialId
     */
    public function del($materialId)
    {
        $findMaterial = WxMaterial::find($materialId);
        \DB::beginTransaction();
        try {
            if (!empty($findMaterial->media_id)){
                $app = EasyWechat::officialAccount();
                $apiRs = $app->material->delete($findMaterial->media_id);
                WxErrorService::checkApiResponse($apiRs);
            }
            $findMaterial->delete();
            \DB::commit();
        } catch (\Exception $e) {
            \DB::rollBack();
            throw new \Exception($e->getMessage());
        }
    }

    /**
     * 获取被动回复数据
     * @param $materialId
     */
    public function getPassiveReplyData($materialId)
    {
        $findMaterial = WxMaterial::find($materialId);
        $newsItems = [];
        if ($findMaterial->news){
            foreach ($findMaterial->news as $index => $newVal){
                $newsItems[] = new NewsItem([
                    'title' => $newVal->title ?? '',
                    'description' => $newVal->digest ?? '',
                    'url' => !empty($newVal->news_click_url) ? $newVal->news_click_url : route('wechat.news.view', ['new_id'=>$newVal->new_id]),
                    'image' => $newVal->thumb_view_url ?? '',
                ]);
            }
        }
        $news = new News($newsItems);
        return $news;
    }

    /**
     * 获取微信mediaId，只有永久素材才能生成mediaId
     * @param $materialId 素材主键ID
     * @param $reUpload 是否重新上传
     * @return string 素材media_id
     */
    public function getMediaId($materialId, $reUpload = false)
    {
        $findMaterial = WxMaterial::find($materialId);
        if ($findMaterial->is_forever == 0) {
            throw new \Exception('必须是永久素材才能获取mediaId');
        }
        if (empty($findMaterial['media_id']) || $reUpload) {
            \DB::beginTransaction();
            try {
                $app = EasyWechat::officialAccount();
                if (empty($findMaterial->news)) {
                    throw new \Exception('图文列表不能为空');
                }
                $thumbService = new WxMaterialThumb();
                $articleList = [];
                foreach ($findMaterial->news as $new) {
                    //永久素材上传封面图
                    $thumbData = $thumbService->save([
                        'title' => $new['title'] . '-封面图',
                        'is_forever' => $findMaterial->is_forever,
                        'view_url' => $new['thumb_view_url'],
                    ]);
                    $new->thumb_material_id = $thumbData['material_id'] ?? '';
                    $new->thumb_media_id = $thumbData['media_id'];
                    $new->save();
                    //组装图文数据
                    $articleList[] = new Article([
                        'title' => $new->title,//标题
                        'thumb_media_id' => $new->thumb_media_id,//图文消息的封面图片素材id
                        'show_cover' => $new->show_cover_pic ?? 0,//是否显示封面
                        'author' => $new->author ?? '',//作者
                        'digest' => empty($new->digest) ? mb_substr(strip_tags($new->content), 0, 64, 'utf-8') : $new->digest,
                        'content' => $this->replaceContentImg($new->content),//图文消息的具体内容
                        'source_url' => $new->content_source_url,//图文消息的原文地址
                        'need_open_comment' => $new->need_open_comment ?? 0,//是否打开评论
                        'only_fans_can_comment' => $new->only_fans_can_comment ?? 0,//是否粉丝才可评论
                    ]);
                }
                //上传图文
                if (!empty($findMaterial->media_id)){//更新素材
                    foreach ($articleList as $index => $article){
                        $apiRs = $app->material->updateArticle($findMaterial->media_id, $article, $index);
                        WxErrorService::checkApiResponse($apiRs);
                    }
                }else{
                    $apiRs = $app->material->uploadArticle($articleList);
                    WxErrorService::checkApiResponse($apiRs);
                }
                $findMaterial->media_id = $apiRs['media_id'];
                $findMaterial->save();
                \DB::commit();
            } catch (\Exception $e) {
                \DB::rollBack();
                throw new \Exception($e->getMessage());
            }
        }
        return $findMaterial->media_id;
    }

    /**
     * 替换微信图片为微信图片地址
     * @param $content
     * @return mixed
     * @throws \Exception
     */
    private function replaceContentImg($content)
    {
        $pattern = '/<img.*?src="([^"]*?)".*?/';
        preg_match_all($pattern, $content, $arr);
        $imgList = $arr[1];
        $wxImgList = [];
        //批量上传到微信
        foreach ($imgList as $imgUrl) {
            //上传图片到微信端
            $wxImgUrl = $this->getWxViewUrl($imgUrl);
            //重试一次
            if (empty($wxImgUrl)) {
                $wxImgUrl = $this->getWxViewUrl($imgUrl);
            }
            $wxImgList[] = $wxImgUrl;
        }
        $content = str_replace($imgList, $wxImgList, $content);
        return $content;
    }

    /**
     * 提供图片访问地址转换成微信图片访问地址
     * @param $viewUrl
     * @return mixed
     * @throws \Exception
     */
    public function getWxViewUrl($viewUrl)
    {
        $findNewImg = WxMaterialNewImg::where('view_url', $viewUrl)->first();
        if (empty($findNewImg)) {
            $app = EasyWechat::officialAccount();
            //拉取远程图片到本地
            $sysFileSer = new SysFileService();
            $localFileInfo = $sysFileSer->getLocalFileInfoByRemoteUrl($viewUrl);

            $apiRs = $app->material->uploadArticleImage($localFileInfo['local_file_path']);
            WxErrorService::checkApiResponse($apiRs);
            $findNewImg = new WxMaterialNewImg;
            $findNewImg->view_url = $viewUrl;
            $findNewImg->wx_view_url = $apiRs['url'];
            $findNewImg->save();
        }
        return $findNewImg->wx_view_url;
    }

    /**
     * 同步线上数据到本地数据
     */
    public function sync()
    {
        // TODO: Implement sync() method.
    }
}